using Bluno.Core;
using GalaSoft.MvvmLight;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Bluno.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase,Core.ISerialHandler
    {
        private System.Threading.Tasks.TaskScheduler UIScheduler;
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real"
            ////}
            UIScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }

        private BlunoDevice _currentDevice;

        public BlunoDevice CurrentDevice
        {
            get { return _currentDevice; }
            set 
            {
                if (_currentDevice!=null)
                {
                    _currentDevice.SerialHandler = null;
                    _currentDevice.Disconnect();
                }
                _currentDevice = value;
                _currentDevice.Connect();
                _currentDevice.SerialHandler = this;
            }
        }


        /// <summary>
        /// The <see cref="DeviceList" /> property's name.
        /// </summary>
        public const string DeviceListPropertyName = "DeviceList";

        private List<BlunoDevice> _deviceList = new List<BlunoDevice>();

        /// <summary>
        /// Sets and gets the DeviceList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public List<Bluno.Core.BlunoDevice> DeviceList
        {
            get
            {
                return _deviceList;
            }

            set
            {
                if (_deviceList == value)
                {
                    return;
                }

                //RaisePropertyChanging(DeviceListPropertyName);
                _deviceList = value;
                RaisePropertyChanged(DeviceListPropertyName);
            }
        }

        public async Task ScanDevices()
        {
            DeviceList=await Bluno.Core.BlunoDevice.ScanBlunoDevices();
        }


        /// <summary>
        /// The <see cref="Temprature" /> property's name.
        /// </summary>
        public const string TempraturePropertyName = "Temprature";

        private float _temprature = 0;

        /// <summary>
        /// Sets and gets the Temprature property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public float Temprature
        {
            get
            {
                return _temprature;
            }

            set
            {
                if (_temprature == value)
                {
                    return;
                }

                _temprature = value;
                RaisePropertyChanged(TempraturePropertyName);
            }
        }


        public void GetTemp()
        {
            CurrentDevice.Send(AccessoryShield.TempratureCommand.ToString());
        }

        public async Task ProcessData(string data, System.DateTimeOffset timeStamp)
        {
            PlanProtocol result;
            try
            {
                result = PlanProtocol.Parse(data);
            }
            catch (System.Exception ex)
            {
                //TODO: log exception

                return;
            }
            await Task.Factory.StartNew(()=> { modifyUIValue(result); },Task.Factory.CancellationToken,TaskCreationOptions.None, UIScheduler);
            
        }
        private void modifyUIValue(PlanProtocol result)
        {
            AccessoryShield.ShieldComponents command = (AccessoryShield.ShieldComponents)System.Enum.Parse(typeof(AccessoryShield.ShieldComponents), result.Command);
            switch (command)
            {
                case AccessoryShield.ShieldComponents.BUZZER:
                    break;
                case AccessoryShield.ShieldComponents.RELAY:
                    break;
                case AccessoryShield.ShieldComponents.DISP:
                    break;
                case AccessoryShield.ShieldComponents.RGBLED:
                    break;
                case AccessoryShield.ShieldComponents.TEMP:
                    this.Temprature = result.Contents[0];
                    break;
                case AccessoryShield.ShieldComponents.HUMID:
                    break;
                case AccessoryShield.ShieldComponents.KNOB:
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// The <see cref="BuzzerEnabled" /> property's name.
        /// </summary>
        public const string BuzzerEnabledPropertyName = "BuzzerEnabled";

        private bool _buzzerEnabled = false;

        /// <summary>
        /// Sets and gets the BuzzerEnabled property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool BuzzerEnabled
        {
            get
            {
                return _buzzerEnabled;
            }

            set
            {
                if (_buzzerEnabled == value)
                {
                    return;
                }
                if (CurrentDevice!=null)
                {
                    var cmd = AccessoryShield.BuzzerCommand;
                    cmd.Contents.Add(value ? 1 : 0);
                    CurrentDevice.Send(cmd);
                }

                _buzzerEnabled = value;
                RaisePropertyChanged(BuzzerEnabledPropertyName);
            }
        }

        
    }
}